package com.andnnl.jm;

/**
 * Created by chenss on 2022/5/23.
 */

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;
import cn.hutool.crypto.symmetric.DESede;
import org.mvel2.templates.util.io.StandardOutputStream;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

public class DesUtil {

    private static final ConcurrentHashMap<String, DES> desHashMap = new ConcurrentHashMap<>();


    private static DES getDes(String key) {
        return Optional.ofNullable(desHashMap.get(key)).orElseGet(() ->
                {
                    DES des = SecureUtil.des(Base64.encode(key).getBytes());
                    desHashMap.put(key, des);
                    return des;
                }
        );
    }

    private static DES getDes2(String key) {
        return desHashMap.computeIfAbsent(key, k -> SecureUtil.des(Base64.encode(k).getBytes()));
    }


    /**
     * 加密
     *
     * @param key:密钥
     * @param encryptStr: 需加密字符串
     * @return: java.lang.String
     * @Author: ZhangRui
     * @Date: 2021/6/30
     */
    public static String encrypt(String key, String encryptStr) {
        DES des = getDes(key);
        return des.encryptHex(encryptStr);
    }

    /**
     * 解密
     *
     * @param key:密钥
     * @param decryptStr: 解密字符串
     * @return: java.lang.String
     * @Author: ZhangRui
     * @Date: 2021/6/30
     */

    public static String decrypt(String key, String decryptStr) {
        try {
            DES des = getDes(key);
            return des.decryptStr(decryptStr);
        } catch (Exception e) {
            return null;
        }
    }


    public static String encrypt2(String content, String slatKey, String vectorKey) throws Exception {
        //改了填充方式
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES");

        IvParameterSpec iv = vectorKey == null ? null : new IvParameterSpec(vectorKey.getBytes());

        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

        byte[] encrypted = cipher.doFinal(content.getBytes());

        return Base64.encode(encrypted);
    }

    public static String encrypt3(String content, String slatKey, String vectorKey) throws Exception {
        //改了填充方式
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES");

        IvParameterSpec iv = vectorKey == null ? null : new IvParameterSpec(vectorKey.getBytes());

        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

        byte[] encrypted = cipher.doFinal(content.getBytes());

        return ByteUtil.byteArray2HexString(encrypted);
    }

    public static void main(String[] args) throws Exception {
        DES des = getDes("S2s4eTZv");
        byte[] roots = des.encrypt("root");
        String roots1 = new String(roots);

//        System.err.println(root);
        //Kk8y6o84zUk=
//        String s = encrypt2("Asdfg123456-", "12345b06ee341234", "12345b06ee341234");
//        System.out.println(s);
        byte[] rs = Base64.decode("Kk8y6o84zUk=");
        System.out.println("b:" + new String(rs));
        String hexKey = ByteUtil.byteArray2HexString(rs);//2a4f32ea8f38cd49
        System.out.println("hexKey:" + hexKey);
        System.out.println("AES:" + encrypt3("root", hexKey, null));
        DES d = new DES(rs);
        System.out.println("DES:" + d.encryptHex("root"));//038278684c555c36
        //d83e4f0c98daebbd
        DES d3 = new DES(Mode.ECB, Padding.PKCS5Padding, "S2s4eTZv".getBytes());//"S2s4eTZv".getBytes()
        System.out.println("ECB:" + d3.encryptHex("root"));//038278684c555c36

        DES d4 = new DES(Mode.CBC, Padding.PKCS5Padding, rs);//"S2s4eTZv".getBytes()
        System.out.println("CBC:" + d4.encryptHex("root"));//ca8e3a048ab38aec

//        DESede d2 = SecureUtil.desede();
//        System.out.println(d2.encryptHex("root"));//038278684c555c36
    }

}